package com.gzck.gzck_verson2.webSocket;

import cn.hutool.core.util.ObjectUtil;
import com.gzck.gzck_verson2.pojo.MessageFrame;
import com.gzck.gzck_verson2.webSocket.CRC;
import com.gzck.gzck_verson2.webSocket.ModbusMessageParser;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

@Component
public class ModbusTcpServer {
    private ServerSocket serverSocket;
    ModbusMessageParser modbusMessageParser = new ModbusMessageParser();
    CRC crc = new CRC();

    @PreDestroy
    public void closeServerSocket() {
        try {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void socketServer() {
        try {
            this.serverSocket = new ServerSocket(3333);
            System.out.println("Modbus TCP Server started. Waiting for connections...");

            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("Device connected from: " + socket.getInetAddress().getHostAddress());
                new Thread(new ModbusHandler(socket)).start();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class ModbusHandler implements Runnable {
        private final Socket socket;
        private final ByteArrayOutputStream messageBuffer = new ByteArrayOutputStream();

        ModbusHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                InputStream inputStream = socket.getInputStream();
                OutputStream outputStream = socket.getOutputStream();

                byte[] buffer = new byte[1024];
                int bytesRead;

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    messageBuffer.write(buffer, 0, bytesRead);

                    checkForCompleteMessages();

                    String response = "Your Modbus Response Data";
                    outputStream.write(response.getBytes());
                    outputStream.flush();
                }

                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void checkForCompleteMessages() {
            byte[] buffer = messageBuffer.toByteArray();

            // 检查是否有足够的字节来形成一个消息
            if (buffer.length < 64) {
                return;
            }

            // 在这里添加检查完整消息的逻辑，然后进行解析
//            String hexMessages = DatatypeConverter.printHexBinary(buffer);
            String hexMessages = "7E7E0122000000019999320153020033240129154601F1F1220000000150F0F024012915462822000457403D22000443772622000436352522000444422422000434802322000395982222001525512122000796582022000913321F22000916821E22000903481D22000890741C22000772741B22000727631A2200140562182200159210172200043228162200046041152200048220142200048897132200046897122200050629112200085830102200082159372200000132362AFF00000000402AFF00000001422200000004432200000028312AFF000000034122000000153F2AFF000000012E2AFF000000002D2AFF000000002C22000000712B2AFF000000012A2AFF000000002922000001733A2B00057220003B2B00057490005F2B00299490005E2B00288120005D2B00300600005C2B00286980005B2B00291220005A2B0030383000592B0029257000582B00278860000000003812000000000003556F";

            String toParser = hexMessages;

            System.out.println("Received data: " + hexMessages);

            // 提取校验部分之前的部分
            String substring = hexMessages.substring(0, hexMessages.length() - 4);

            // 将十六进制字符串转换为字节数组
            byte[] dataBytes = DatatypeConverter.parseHexBinary(substring);

            // 计算 CRC
            int crcCheck = crc.crcCheck(dataBytes, dataBytes.length);

            // 将 CRC 转换为十六进制字符串
            String crcHex = Integer.toHexString(crcCheck).toUpperCase();

            // 提取原始数据中的 CRC 部分
            String originalCrc = hexMessages.substring(hexMessages.length() - 4).toUpperCase();

            if (ObjectUtil.notEqual(crcHex, originalCrc)) {
                System.out.println("CRC校验失败");
                return;
            }

            System.out.println("CRC校验通过");

            System.out.println("开始进行解析\n");

            MessageFrame messageFrame = modbusMessageParser.parseMessage(toParser);

            System.out.println(messageFrame.toString());
            System.out.println("测试结束\n\n\n\n");

            // 处理完整消息后，重置缓冲区
            messageBuffer.reset();
        }
    }
}
